﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Configuration;
using TeamCitySharp;
using Teamboard.Helpers;
using System.IO;
using System.Xml;
using System.Xml.XPath;

namespace Teamboard.Configuration
{
    public partial class Form1 : Form
    {
        string projectsFilePath = Path.Combine(Application.StartupPath, "projects.xml");
        string webConfigPath = Path.Combine(Application.StartupPath, "web.config");
        
        public Form1()
        {
            InitializeComponent();

            FolderBrowserDialog fbd = new FolderBrowserDialog();
            if (fbd.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
            {
                projectsFilePath = Path.Combine(fbd.SelectedPath, "projects.xml");
                webConfigPath = Path.Combine(fbd.SelectedPath, "web.config");
            
                try
                {
                    XmlDocument doc = new XmlDocument();
                    doc.Load(webConfigPath);
                    var nav = doc.CreateNavigator();
                    txtServer.Text = ReadSetting(nav, "BuildServerName");
                    txtUserName.Text = ReadSetting(nav, "UserName");
                    txtPassword.Text = ReadSetting(nav, "Password");
                    chkUseGuest.Checked = ReadSetting(nav, "LoginAsGuest").Equals(bool.TrueString, StringComparison.InvariantCultureIgnoreCase);
                    chkSecure.Checked = ReadSetting(nav, "UseSSL").Equals(bool.TrueString, StringComparison.InvariantCultureIgnoreCase);

                    LoadTree(CreateTeamCityClient());
                }
                catch
                {
                    MessageBox.Show("Error loading configuration");
                }
            }
        }

        private string ReadSetting(XPathNavigator nav, string property)
        {
            var xPath = string.Format("/configuration/applicationSettings/Teamboard.Properties.Settings/setting[@name='{0}']/value", property);
            return nav.SelectSingleNode(xPath).Value;
        }

        private void chkUseGuest_CheckedChanged(object sender, EventArgs e)
        {
            txtUserName.Enabled = txtPassword.Enabled = !chkUseGuest.Checked;
        }

        private void btnTest_Click(object sender, EventArgs e)
        {
            try
            {
                TeamCityClient clnt = CreateTeamCityClient();

                var serverInfo = clnt.ServerInfo();
                var message = string.Format("Successfully communicated to teamcity server.\r\nServer Version : {0}", serverInfo.BuildNumber);
                MessageBox.Show(message, "Teamboard Configuration");

                LoadTree(clnt);
                
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error communicating to teamcity server. " + Environment.NewLine + ex.Message, "Teamboard Configuration");
            }
        }

        private TeamCityClient CreateTeamCityClient()
        {
            TeamCityClient clnt = new TeamCityClient(txtServer.Text);
            if (chkUseGuest.Checked)
            {
                clnt.Connect(string.Empty, string.Empty, true);
            }
            else
            {
                clnt.Connect(txtUserName.Text, txtPassword.Text);
            }
            return clnt;
        }

        private void LoadTree(TeamCityClient clnt)
        {
            SettingsManager settings = new SettingsManager(projectsFilePath);
            Teamboard.TeamCity.TeamCityHelper helper = new TeamCity.TeamCityHelper();
            helper.Client = clnt;
            treeList.Nodes.Clear();
            var projects = helper.GetProjectsAndConfigurations();
            var selectedProjects = settings.GetProjectsList();
            foreach (var project in projects)
            {
                var projectNode = treeList.Nodes.Add(project.Id, project.Name);
                projectNode.Checked = selectedProjects.Contains(project.Name, StringComparer.InvariantCultureIgnoreCase);

                var selectedConfigurations = settings.GetProjectConfigurations(project.Name);
                foreach (var conf in project.Configurations)
                {
                    var confNode = projectNode.Nodes.Add(conf.Id, conf.Name);
                    confNode.Checked = selectedConfigurations.Contains(conf.Name, StringComparer.InvariantCultureIgnoreCase);
                }
            }
        }

        private void treeList_AfterCheck(object sender, TreeViewEventArgs e)
        {
            if (e.Node.Parent == null && !e.Node.Checked)
            {
                foreach (TreeNode node in e.Node.Nodes)
                {
                    node.Checked = false;
                }
            }
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            if (File.Exists(projectsFilePath))
            {
                File.Delete(projectsFilePath);
            }

            using (XmlWriter xmlWriter = XmlWriter.Create(projectsFilePath, new XmlWriterSettings() { Encoding = Encoding.UTF8, Indent = true }))
            {
                xmlWriter.WriteStartElement("projects");

                foreach (TreeNode treeNode in treeList.Nodes)
                {
                    if (treeNode.Checked)
                    {
                        xmlWriter.WriteStartElement("project");
                        xmlWriter.WriteAttributeString("name", treeNode.Text);
                        xmlWriter.WriteStartElement("configurations");
                        foreach (TreeNode childNode in treeNode.Nodes)
                        {
                            if (childNode.Checked)
                            {
                                xmlWriter.WriteStartElement("configuration");
                                xmlWriter.WriteAttributeString("name", childNode.Text);
                                xmlWriter.WriteEndElement();
                            }
                        }
                        xmlWriter.WriteEndElement();
                        xmlWriter.WriteEndElement();
                    }
                }

                xmlWriter.WriteEndElement();
            }

            Application.Exit();
        }

        private void chkShowAllProjects_CheckedChanged(object sender, EventArgs e)
        {
            treeList.Enabled = !chkShowAllProjects.Checked;
        }


    }
}
